﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using LynxWiki.DomainModel;
using LynxWiki.Filters;
using LynxWiki.Search;
using LynxWiki.ViewModels;
using LynxWiki.Repository;

namespace LynxWiki.Controllers
{
    [InitializeSimpleMembership]
    public class TopicDiscussionController : Controller
    {
        //
        // GET: /TopicDiscussion/

        [TopicActionFilter]
        public ActionResult Index(string topicName)
        {
            ViewBag.Title = "Index";
            ViewBag.PagePath = "";
            ViewBag.TabbedMenuList = BuildMenuTabs();
            TopicVersionViewData tvd = new TopicVersionViewData();
            tvd.TopicName = topicName;
            return View(tvd);
        }

        [TopicActionFilter]
        public ActionResult Page(string pagePath)
        {
            ViewBag.Title = "QuickLink";
            ViewBag.PagePath = pagePath;
            TopicVersionViewData tvd = new TopicVersionViewData();
            tvd.TopicName = pagePath.Substring(pagePath.LastIndexOf("/") + 1);
            WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath(""));
            WikiDirectory wd = wtr.GetWikiDirectoryInfo(Server.MapPath(""));
            if (wtr.GetTopicVersionCount(tvd.TopicName) > 0) {
                ViewBag.TabbedMenuList = BuildMenuTabs(pagePath);
                tvd.Topic = wtr.GetCurrentVersion(tvd.TopicName);
                if (!DenyRead(tvd.Topic)) {
                    return View("Index", tvd);
                }
                else {
                    return RedirectToRoute("ShowAccessDenied", new { action = "ShowAccessDenied", controller = "TopicDiscussion", topicName = tvd.TopicName });
                }
            }
            else {
                return RedirectToRoute("PageDisplay", new { action = "Edit", controller = "TopicDiscussion", pagePath });
            }
        }

        [HttpPost]
        [TopicActionFilter]
        public ActionResult Page(FormCollection fc)
        {
            ViewBag.Title = "QuickLink";
            string pagePath = fc["PagePath"];
            pagePath = pagePath.Substring(0, pagePath.LastIndexOf("/") + 1) + fc["TopicBarInputBox"];
            ViewBag.TabbedMenuList = BuildMenuTabs(pagePath);
            //opicName = fc["topicBarInputBox"];
            return RedirectToRoute("PageDisplay", new { action = "Page", controller = "WikiTopic", pagePath });
        }

        [TopicActionFilter]
        public ActionResult History(string pagePath)
        {
            try {
                ViewBag.Title = "QuickLink";
                ViewBag.PagePath = pagePath;
                ViewBag.User = User.Identity.Name;
                TopicVersionViewData tvd = new TopicVersionViewData();
                tvd.TopicName = pagePath.Substring(pagePath.LastIndexOf("/") + 1);
                tvd.PagePath = pagePath;
                ViewBag.TabbedMenuList = BuildMenuTabs(pagePath);
                WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath("~\\" + tvd.PagePath.Substring(0, tvd.PagePath.LastIndexOf("/"))));
                List<WikiTopicHistoryListingViewData> wthlvd = new List<WikiTopicHistoryListingViewData>();
                IEnumerable<TopicVersion> tvl = wtr.GetTopicVersions(tvd.TopicName);
                foreach (TopicVersion tv in tvl) {
                    WikiTopicHistoryListingViewData tvh = new WikiTopicHistoryListingViewData();
                    tvh.TopicName = tv.TopicName;
                    tvh.WikiDir = pagePath;
                    tvh.CreatedOn = tv.CreatedOn;
                    tvh.Creator = tv.Creator;
                    tvh.Version = tv.Version;
                    tvh.TopicBody = tv.Body;
                    wthlvd.Add(tvh);
                }
                return View(wthlvd);
            }
            catch {
                return View();
            }
        }

        //
        // GET: /TopicDiscussion/Edit/5

        [TopicActionFilter]
        public ActionResult Edit(string pagePath)
        {
            ViewBag.CaptchaSetting = (ConfigurationManager.AppSettings["CaptchaRequiredOnEdit"] == "true" ? "true" : "false");
            ViewBag.Title = "QuickLink";
            ViewBag.PagePath = pagePath;
            ViewBag.User = User.Identity.Name;
            TopicVersionViewData tvd = new TopicVersionViewData();
            tvd.TopicName = pagePath.Substring(pagePath.LastIndexOf("/") + 1);
            tvd.PagePath = pagePath;
            WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath("~\\" + pagePath.Substring(0, pagePath.LastIndexOf("/"))));
            WikiDirectory wd = wtr.GetWikiDirectoryInfo(Server.MapPath(pagePath.Substring(0, pagePath.LastIndexOf("/") + 1)));
            if (wtr.GetTopicVersionCount(tvd.TopicName) > 0) {
                tvd.Topic = wtr.GetCurrentVersion(tvd.TopicName);
                ViewBag.TabbedMenuList = BuildMenuTabs(pagePath);
                return View("Edit", tvd);
            }
            else {
                // provide default content
                tvd.Topic = new TopicVersion();
                tvd.Topic.WikiText = @"!!Level 2 Header for a New Discussion

Edit the content of this message to create your new discussion.

";
                tvd.Topic.Version = 0;
                ViewBag.TabbedMenuList = BuildMenuTabs(pagePath);
                return View("Edit", tvd);
            }
        }

        //
        // POST: /WikiTopic/Edit/5

        [HttpPost]
        [ValidateInput(false)]
        [ActionName("EditDiscussion")]
        [AcceptSubmitButton(Name = "btnNewVersion", Value = "New Version")]
        [TopicActionFilter]
        [MaliciousActivityChecksFilter]
        public ActionResult btnNewVersion(TopicVersionViewData tvd)
        {
            if (ConfigurationManager.AppSettings["CaptchaRequiredOnEdit"] == "true") {
                if (Session["CaptchaDiscussion"] == null || Session["CaptchaDiscussion"].ToString() != tvd.CaptchaInput) {
                    ViewBag.CaptchaSetting = "true";
                    ModelState.AddModelError("CaptchaInput", "Wrong value entered, please try again.");
                    ViewBag.Title = "QuickLink";
                    ViewBag.PagePath = tvd.PagePath;
                    ViewBag.User = User.Identity.Name;
                    ViewBag.TabbedMenuList = BuildMenuTabs(tvd.PagePath);
                    return View("Edit", tvd);
                }
            }
            try {
                // TODO: Add update logic here

                WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath("~\\" + tvd.PagePath.Substring(0, tvd.PagePath.LastIndexOf("/"))));
                TopicVersion tv = new TopicVersion(tvd.TopicName, wtr.WikiDir, tvd.Topic.WikiText, User.Identity.Name,
                    ++tvd.Topic.Version, tvd.Topic.Body, tvd.ListDenyReadUser, tvd.ListDenyReadRole, tvd.ListAllowEditUser, tvd.ListAllowEditRole, tvd.Tags, tvd.Topic.EditReason);
                tvd.Topic = tv;
                wtr.Add(tv);
                return RedirectToRoute("PageDisplay", new { action = "Page", controller = "TopicDiscussion", pagePath = tvd.PagePath });
            }
            catch {
                return View();
            }
        }

        [HttpPost]
        [ValidateInput(false)]
        [ActionName("EditDiscussion")]
        [AcceptSubmitButton(Name = "btnMinorUpdate", Value = "Minor Update")]
        [TopicActionFilter]
        [MaliciousActivityChecksFilter]
        public ActionResult btnMinorUpdate(TopicVersionViewData tvd)
        {
            if (ConfigurationManager.AppSettings["CaptchaRequiredOnEdit"] == "true") {
                if (Session["CaptchaDiscussion"] == null || Session["CaptchaDiscussion"].ToString() != tvd.CaptchaInput) {
                    ViewBag.CaptchaSetting = "true";
                    ModelState.AddModelError("CaptchaInput", "Wrong value entered, please try again.");
                    ViewBag.Title = "QuickLink";
                    ViewBag.PagePath = tvd.PagePath;
                    ViewBag.User = User.Identity.Name;
                    ViewBag.TabbedMenuList = BuildMenuTabs(tvd.PagePath);
                    return View("Edit", tvd);
                }
            }
            try {
                // TODO: Add update logic here

                WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath("~\\" + tvd.PagePath.Substring(0, tvd.PagePath.LastIndexOf("/"))));
                TopicVersion tv = new TopicVersion(tvd.TopicName, wtr.WikiDir,  tvd.Topic.WikiText, User.Identity.Name,
                    tvd.Topic.Version, tvd.Topic.Body, String.Empty, string.Empty, string.Empty, string.Empty,
                    tvd.Tags, String.Empty,
                    tvd.CreateListFromMinorUpdateDetails(), User.Identity.Name, tvd.MinorUpdate);
                tvd.Topic = tv;
                wtr.Update(tv);
                return RedirectToRoute("PageDisplay", new { action = "Page", controller = "TopicDiscussion", pagePath = tvd.PagePath });
            }
            catch {
                return View();
            }
        }

        [HttpPost]
        [ValidateInput(false)]
        [ActionName("EditDiscussion")]
        [AcceptSubmitButton(Name = "btnPreview", Value = "Preview")]
        [TopicActionFilter]
        public ActionResult btnPreview(TopicVersionViewData tvd)
        {
            try {
                // TODO: Add update logic here
                this.Session.Remove("__MyPreviewText");
                this.Session.Add("__MyPreviewText", tvd.Topic.HtmlText);
                return RedirectToAction("ShowPreview");
            }
            catch {
                return View();
            }
        }

        [HttpPost]
        [ValidateInput(false)]
        [ActionName("TopicHistory")]
        [AcceptSubmitButton(Name = "btnPreview", Value = "Preview")]
        [TopicActionFilter]
        public ActionResult btnPreview(FormCollection fc)
        {
            try {
                TopicVersion tv = new TopicVersion();
                tv.TopicName = fc[0];
                //tv.Version = fc["Version"] as Int32;
                tv.Body = fc[3];
                TopicVersionViewData tvd = new TopicVersionViewData(tv);
                // TODO: Add update logic here
                this.Session.Remove("__MyPreviewText");
                this.Session.Add("__MyPreviewText", tvd.Topic.HtmlText);
                return RedirectToAction("ShowPreview");
            }
            catch {
                return View();
            }
        }

        [HttpPost]
        [ValidateInput(false)]
        [ActionName("TopicHistory")]
        [AcceptSubmitButton(Name = "btnMakeCurrent", Value = "Make Current")]
        [TopicActionFilter]
        [MaliciousActivityChecksFilter]
        public ActionResult btnMakeCurrent(FormCollection fc)
        {
            try {
                string pagePath = fc[2];
                WikiDiscussRepository wtr = new WikiDiscussRepository(Server.MapPath("~\\" + pagePath.Substring(0, pagePath.LastIndexOf("/"))));
                int curVersion = wtr.GetTopicCurrentVersionNumber(fc[0]);
                int getVersion;
                Int32.TryParse(fc[1], out getVersion);
                TopicVersion tv = wtr.GetSpecificVersion(fc[0], getVersion);
                tv.Version = curVersion + 1;
                if (Request.IsAuthenticated) {
                    tv.Creator = User.Identity.Name;
                }
                wtr.Add(tv);
                return RedirectToRoute("PageDisplay", new { action = "Page", controller = "TopicDiscussion", pagePath = pagePath });
            }
            catch {
                return View();
            }
        }

        [TopicActionFilter]
        public ActionResult ShowPreview()
        {
            ViewBag.PreviewText = this.Session["__MyPreviewText"];
            return View("Preview");
        }

        [TopicActionFilter]
        public ActionResult ShowAccessDenied(string topicName)
        {
            ViewBag.TopicName = topicName;
            return View("AccessDenied");
        }

        private bool DenyRead(TopicVersion tv)
        {
            bool testRead = false;
            if (Request.IsAuthenticated) {
                testRead = TopicAccess.DenyRead(User, tv, null);
            }
            else {
                testRead = TopicAccess.DenyRead(null, tv, null);
            }
            return testRead;
        }

        private List<MenuTab> BuildMenuTabs()
        {
            return new List<MenuTab> {
                MenuTab.Create("Topic", "Index", null, "WikiTopic"),
                MenuTab.Create("Discussion", "Index", null, "TopicDiscussion"),
                MenuTab.Create("Read", "Index", null, "TopicDiscussion"),
                MenuTab.Create("Edit", "Edit", null, "TopicDiscussion"),
                MenuTab.Create("History", "History", null, "TopicDiscussion")
            };
        }
        private List<MenuTab> BuildMenuTabs(string pagePath)
        {
            return new List<MenuTab> {
                MenuTab.Create("Topic", "Page", pagePath, "WikiTopic"),
                MenuTab.Create("Discussion", "Page", pagePath, "TopicDiscussion"),
                MenuTab.Create("Read", "Page", pagePath, "TopicDiscussion"),
                MenuTab.Create("Edit", "Edit", pagePath, "TopicDiscussion"),
                MenuTab.Create("History", "History", pagePath, "TopicDiscussion")
            };
        }

        [MaliciousActivityChecksFilter]
        public ActionResult WikiTopicLockAction(string topicName, string wikiDir, string pagePath, string lockAction)
        {
            WikiDirectoryRepository wdr = new WikiDirectoryRepository(Server.MapPath(@"~\" + wikiDir));
            wdr.WikiTopicLockAction(topicName, lockAction);

            return RedirectToRoute("PageDisplay", new { action = "Page", controller = "WikiTopic", pagePath });
        }

    }
}
